package com.hhxy.job;


import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.hhxy.annotation.SystemLog;
import com.hhxy.constants.SystemConstants;
import com.hhxy.handler.exception.CustomException;
import com.hhxy.model.entity.Article;
import com.hhxy.service.ArticleService;
import com.hhxy.utils.redis.RedisCache;
import com.hhxy.utils.response.AppHttpCodeEnum;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author ghp
 * @date 2023/3/24
 * @title 更新文章浏览量的定时任务
 * @description
 */
@Component
// TODO 这里无法使用lombok的@Slf4j注解 不知道是什么原因
public class UpdateViewCountJob {

    @Resource
    private RedisCache redisCache;

    @Resource
    private ArticleService articleService;

    /**
     * 将Redis中的数据同步到MySQL中（更新文章浏览量）
     * 从每分钟的第 0s 开始，每过 5s 执行
     */
    @Scheduled(cron = "0/5 * * * * ?")
    @SystemLog(businessName = "将Redis中的文章访问量同步到MySQL中")
    public void updateViewCount() {
        // 获取redis中文章的浏览量
        Map<String, Integer> viewCountMap = redisCache.getCacheMap(SystemConstants.ARTICLE_VIEW_COUNT);
        // 将从redis中的Map（key为文章id，value为文章访问量）转成List
        List<Article> articles = viewCountMap.entrySet()
                .stream()
                .map(entry ->
                        new Article(Long.valueOf(entry.getKey()), entry.getValue().longValue())
                ).collect(Collectors.toList());
        // 更新到数据库中（注意：一定要先保障）
        for (Article article : articles) {
            // 判断改文章是否存在
            Article a = articleService.getById(article.getId());
            if (Objects.isNull(a)){
                // 说明该篇文章已从MySQL中删除了，没必要再去更新阅读量了
                continue;
            }
            // 更新文章的访问量
            boolean flag = articleService.update(new LambdaUpdateWrapper<Article>()
                    .eq(Article::getId, article.getId())
                    .set(Article::getViewCount, article.getViewCount()));
            if (!flag) {
                throw new CustomException(AppHttpCodeEnum.SYSTEM_ERROR);
            }
        }
    }
}
